﻿using HardcoreGame.Content.Tiles.Natures;
using HardcoreGame.Content.Tiles.Replace;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using Terraria;
using Terraria.GameContent.Generation;
using Terraria.ID;
using Terraria.IO;
using Terraria.ModLoader;
using Terraria.WorldBuilding;

namespace HardcoreGame.Common.Systems
{
    public class ChargeWorldGen : ModSystem
    {
        public static int LavaLayer => (int)((Main.maxTilesY - Main.rockLayer) / 2.0 + Main.rockLayer);
        public override void Load()
        {
            On_WorldGen.UpdateWorld += WorldGen_UpdateWorld;
        }
        private void WorldGen_UpdateWorld(On_WorldGen.orig_UpdateWorld orig)
        {
            orig();
            int x = WorldGen.genRand.Next(10, Main.maxTilesX - 10);
            int y = WorldGen.genRand.Next((int)Main.worldSurface - 1, Main.maxTilesY - 20);
            int yUp = y - 1;
            if (yUp < 10)
            {
                yUp = 10;
            }
            if (Main.tile[x, y] != null && Main.tile[x, y].LiquidAmount <= 32 && Main.tile[x, y].HasUnactuatedTile)
            {
                if (Main.tile[x, y].TileType == 60)
                {
                    if (Main.hardMode && WorldGen.genRand.NextBool(10))
                    {
                        bool create = true;
                        int off = 80;
                        for (int i = x - off; i < x + off; i += 2)
                        {
                            for (int j = y - off; j < y + off; j += 2)
                            {
                                if (i > 1 && i < Main.maxTilesX - 2 && j > 1 && j < Main.maxTilesY - 2 && Main.tile[i, j].HasTile && Main.tile[i, j].TileType == ModContent.TileType<ManaFruit>())
                                {
                                    create = false;
                                    break;
                                }
                            }
                        }
                        if (create)
                        {
                            PlaceJungleTile(x, yUp, (ushort)ModContent.TileType<ManaFruit>(), WorldGen.genRand.Next(3));
                            WorldGen.SquareTileFrame(x, yUp, true);
                            WorldGen.SquareTileFrame(x + 1, yUp + 1, true);
                            if (Main.tile[x, yUp].TileType == ModContent.TileType<ManaFruit>() && Main.netMode == NetmodeID.Server)
                            {
                                NetMessage.SendTileSquare(-1, x, yUp, 4);
                            }
                        }

                    }
                }
            }
        }
        public static void PlaceJungleTile(int X2, int Y2, ushort type, int styleX)
        {

            for (int a = 0; a < 20; a++)
            {
                if (X2 < 5 || X2 > Main.maxTilesX - 5 || Y2 < 5 || Y2 > Main.maxTilesY - 5)
                {
                    return;
                }
                bool place = true;
                for (int i = X2 - 1; i < X2 + 1; i++)
                {
                    for (int j = Y2 - 1; j < Y2 + 1; j++)
                    {
                        if (Main.tile[i, j] == null)
                        {
                            Main.tile[i, j].TileType = type;
                        }
                        if (Main.tile[i, j].HasTile && Main.tile[i, j].TileType != 61 && Main.tile[i, j].TileType != 62 && Main.tile[i, j].TileType != 69 && Main.tile[i, j].TileType != 74 && (type != 236 || Main.tile[i, j].TileType != 233) && (type != 238 || Main.tile[i, j].TileType != 233) && (Main.tile[i, j].TileType != 185 || Main.tile[i, j].TileFrameY != 0))
                        {
                            place = false;
                        }
                        if (type == 98 && Main.tile[i, j].LiquidAmount > 0)
                        {
                            place = false;
                        }
                    }
                    if (Main.tile[i, Y2 + 1] == null)
                    {
                        Main.tile[i, Y2 + 1].TileType = type;
                    }
                    if (!WorldGen.SolidTile(i, Y2 + 1) || Main.tile[i, Y2 + 1].TileType != 60)
                    {
                        place = false;
                    }
                }
                if (place)
                {
                    short typeX = (short)(36 * styleX);
                    Main.tile[X2 - 1, Y2 - 1].TileType = type;
                    Main.tile[X2 - 1, Y2 - 1].TileFrameY = 0;
                    Main.tile[X2 - 1, Y2 - 1].TileFrameX = typeX;
                    Main.tile[X2 - 1, Y2 - 1].TileType = type;
                    Main.tile[X2, Y2 - 1].TileType = type;
                    Main.tile[X2, Y2 - 1].TileFrameY = 0;
                    Main.tile[X2, Y2 - 1].TileFrameX = (short)(18 + typeX);
                    Main.tile[X2, Y2 - 1].TileType = type;
                    Main.tile[X2 - 1, Y2].TileType = type;
                    Main.tile[X2 - 1, Y2].TileFrameY = 18;
                    Main.tile[X2 - 1, Y2].TileFrameX = typeX;
                    Main.tile[X2 - 1, Y2].TileType = type;
                    Main.tile[X2, Y2].TileType = type;
                    Main.tile[X2, Y2].TileFrameY = 18;
                    Main.tile[X2, Y2].TileFrameX = (short)(18 + typeX);
                    Main.tile[X2, Y2].TileType = type;
                    break;
                }
                X2 += WorldGen.genRand.Next(-5, 5);
                Y2 += WorldGen.genRand.Next(-5, 5);
            }

        }
        public override void ModifyWorldGenTasks(List<GenPass> tasks, ref double totalWeight)
        {
            int genIndex = tasks.FindIndex((genpass) => genpass.Name.Equals("Settle Liquids"));
            if (genIndex != -1)
            {
                tasks.Insert(genIndex + 1, new PassLegacy("Campfires", new WorldGenLegacyMethod(Campfires)));
            }

            int genIndex1 = tasks.FindIndex((genpass) => genpass.Name.Equals("Clay"));
            tasks.RemoveAt(genIndex1);
            genIndex1 = tasks.FindIndex((genpass) => genpass.Name.Equals("Micro Biomes"));
            if (genIndex1 != -1)
            {
                tasks.Insert(genIndex1 + 1, new PassLegacy("Better Clay", new WorldGenLegacyMethod(Clay)));
            }

            int genIndex2 = tasks.FindIndex((genpass) => genpass.Name.Equals("Surface Caves"));
            if (genIndex2 != -1)
            {
                tasks.Insert(genIndex2 + 1, new PassLegacy("Mega Caves", new WorldGenLegacyMethod(MegaCaves)));
            }

            int genIndex3 = tasks.FindIndex((genpass) => genpass.Name.Equals("Quick Cleanup"));
            if (genIndex3 != -1)
            {
                tasks.Insert(genIndex3 + 1, new PassLegacy("Dungeon Chains", new WorldGenLegacyMethod(DungeonChains)));
            }

            int genIndex4 = tasks.FindIndex((genpass) => genpass.Name.Equals("Sand"));
            if (genIndex4 != -1)
            {
                tasks.Insert(genIndex4 + 1, new PassLegacy("Smooth Desert", new WorldGenLegacyMethod(SmoothDesert)));
            }

            int genIndex5 = tasks.FindIndex((genpass) => genpass.Name.Equals("Water Plants"));
            if (genIndex5 != -1)
            {
                tasks.Insert(genIndex5, new PassLegacy("Ore Meteorites", new WorldGenLegacyMethod(OreMeteorites)));
            }

            int genIndex6 = tasks.FindIndex((genpass) => genpass.Name.Equals("Remove Water From Sand"));
            if (genIndex6 != -1)
            {
                tasks.Insert(genIndex6 + 1, new PassLegacy("Desert Pillars", new WorldGenLegacyMethod(DesertPillars)));
            }
            int genIndex7 = tasks.FindIndex((GenPass genpass) => genpass.Name.Equals("Remove Water From Sand"));
            if (genIndex7 != -1)
            {
                tasks.Insert(genIndex7 + 1, new PassLegacy("Hardened Sand", new WorldGenLegacyMethod(HardenedSand)));
            }
           
        }       
        private void HardenedSand(GenerationProgress progress, GameConfiguration configuration)
        {
            progress.Message = "Desert Rocks";
            new Random();
            for (int replaceY = 1; replaceY < Main.maxTilesY; replaceY++)
            {
                for (int replaceX = 1; replaceX < Main.maxTilesX; replaceX++)
                {
                    if (Framing.GetTileSafely(replaceX, replaceY).HasTile && (Framing.GetTileSafely(replaceX, replaceY).TileType == 53 || Framing.GetTileSafely(replaceX, replaceY).TileType == 112 || Framing.GetTileSafely(replaceX, replaceY).TileType == 234))
                    {
                        int replace2X = replaceX - 1;
                        int replace2Y = replaceY + 1;
                        bool killtile = false;
                        while (replace2X < replaceX + 2)
                        {
                            if (!Framing.GetTileSafely(replace2X, replace2Y).HasTile)
                            {
                                killtile = true;
                            }
                            if (Framing.GetTileSafely(replace2X, replace2Y).HasTile && !Main.tileSolid[(int)Framing.GetTileSafely(replace2X, replace2Y).TileType])
                            {
                                killtile = true;
                            }
                            replace2X++;
                        }
                        if (killtile)
                        {
                            int tileslope = (int)Main.tile[replaceX, replaceY + 1].Slope;
                            WorldGen.KillTile(replaceX, replaceY + 1, false, false, false);
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 53)
                            {
                                WorldGen.PlaceTile(replaceX, replaceY + 1, ModContent.TileType<Replace1>(), false, false, -1, 0);
                            }
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 112)
                            {
                                WorldGen.PlaceTile(replaceX, replaceY + 1, ModContent.TileType<Replace2>(), false, false, -1, 0);
                            }
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 234)
                            {
                                WorldGen.PlaceTile(replaceX, replaceY + 1, ModContent.TileType<Replace3>(), false, false, -1, 0);
                            }
                            Framing.GetTileSafely(replaceX, replaceY + 1).Slope = (Terraria.ID.SlopeType)(byte)tileslope;
                        }
                    }
                }
            }
            for (int replaceY = 1; replaceY < Main.maxTilesY; replaceY++)
            {
                for (int replaceX = 1; replaceX < Main.maxTilesX; replaceX++)
                {
                    if (Framing.GetTileSafely(replaceX, replaceY).HasTile && Framing.GetTileSafely(replaceX, replaceY).TileType == 53)
                    {
                        int tileslope = (int)Main.tile[replaceX, replaceY].Slope;
                        WorldGen.KillTile(replaceX, replaceY, false, false, false);
                        WorldGen.PlaceTile(replaceX, replaceY, ModContent.TileType<Replace9>(), false, false, -1, 0);
                        Framing.GetTileSafely(replaceX, replaceY).Slope = (Terraria.ID.SlopeType)(byte)tileslope;
                    }
                }
            }
            for (int replaceY = 1; replaceY < Main.maxTilesY; replaceY++)
            {
                for (int replaceX = 1; replaceX < Main.maxTilesX; replaceX++)
                {
                    if (Framing.GetTileSafely(replaceX, replaceY).HasTile)
                    {
                        if ((int)Framing.GetTileSafely(replaceX, replaceY).TileType == ModContent.TileType<Replace1>())
                        {
                            WorldGen.TileRunner(replaceX, replaceY, 8.0, 1, 397, false, 0f, 0f, false, true);
                        }
                        if ((int)Framing.GetTileSafely(replaceX, replaceY).TileType == ModContent.TileType<Replace2>())
                        {
                            WorldGen.TileRunner(replaceX, replaceY, 8.0, 1, 398, false, 0f, 0f, false, true);
                        }
                        if ((int)Framing.GetTileSafely(replaceX, replaceY).TileType == ModContent.TileType<Replace3>())
                        {
                            WorldGen.TileRunner(replaceX, replaceY, 8.0, 1, 399, false, 0f, 0f, false, true);
                        }
                    }
                    if ((int)Framing.GetTileSafely(replaceX, replaceY).TileType == ModContent.TileType<Replace9>() || Framing.GetTileSafely(replaceX, replaceY).TileType == 112 || Framing.GetTileSafely(replaceX, replaceY).TileType == 234)
                    {
                        int replace2X = replaceX;
                        int replace2Y = replaceY;
                        int depth = 1;
                        while (Framing.GetTileSafely(replace2X, replace2Y).HasTile || Framing.GetTileSafely(replace2X, replace2Y).WallType != 0)
                        {
                            depth++;
                            replace2Y--;
                        }
                        if (depth > 10 && WorldGen.genRand.Next(1, 40) <= depth - 10)
                        {
                            if ((int)Framing.GetTileSafely(replaceX, replaceY).TileType == ModContent.TileType<Replace9>())
                            {
                                WorldGen.TileRunner(replaceX, replaceY, 4.0, 1, 397, false, 0f, 0f, false, true);
                            }
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 112)
                            {
                                WorldGen.TileRunner(replaceX, replaceY, 4.0, 1, 398, false, 0f, 0f, false, true);
                            }
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 234)
                            {
                                WorldGen.TileRunner(replaceX, replaceY, 4.0, 1, 399, false, 0f, 0f, false, true);
                            }
                        }
                    }
                }
            }
            for (int replaceY = 1; replaceY < Main.maxTilesY; replaceY++)
            {
                for (int replaceX = 1; replaceX < Main.maxTilesX; replaceX++)
                {
                    if (Framing.GetTileSafely(replaceX, replaceY).HasTile && Framing.GetTileSafely(replaceX, replaceY).WallType == 2 && (Framing.GetTileSafely(replaceX, replaceY).TileType == 397 || Framing.GetTileSafely(replaceX, replaceY).TileType == 398 || Framing.GetTileSafely(replaceX, replaceY).TileType == 399))
                    {
                        WorldGen.KillWall(replaceX, replaceY, false);
                    }
                }
            }
            for (int replaceY = 1; replaceY < Main.maxTilesY; replaceY++)
            {
                for (int replaceX = 1; replaceX < Main.maxTilesX; replaceX++)
                {
                    if (Framing.GetTileSafely(replaceX, replaceY).HasTile)
                    {
                        if ((int)Framing.GetTileSafely(replaceX, replaceY).TileType == ModContent.TileType<Replace9>())
                        {
                            int tileslope = (int)Main.tile[replaceX, replaceY].Slope;
                            WorldGen.KillTile(replaceX, replaceY, false, false, false);
                            WorldGen.PlaceTile(replaceX, replaceY, 53, false, false, -1, 0);
                            Framing.GetTileSafely(replaceX, replaceY).Slope = (Terraria.ID.SlopeType)(byte)tileslope;
                        }
                        if (Framing.GetTileSafely(replaceX + 1, replaceY).HasTile && Framing.GetTileSafely(replaceX + 1, replaceY + 1).HasTile && Framing.GetTileSafely(replaceX, replaceY + 1).HasTile && Framing.GetTileSafely(replaceX - 1, replaceY + 1).HasTile && Framing.GetTileSafely(replaceX - 1, replaceY).HasTile && Framing.GetTileSafely(replaceX - 1, replaceY - 1).HasTile && Framing.GetTileSafely(replaceX, replaceY - 1).HasTile && Framing.GetTileSafely(replaceX + 1, replaceY - 1).HasTile && Main.tileSolid[(int)Framing.GetTileSafely(replaceX + 1, replaceY).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(replaceX + 1, replaceY + 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(replaceX, replaceY + 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(replaceX - 1, replaceY + 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(replaceX - 1, replaceY).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(replaceX - 1, replaceY - 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(replaceX, replaceY - 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(replaceX + 1, replaceY - 1).TileType])
                        {
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 53 || Framing.GetTileSafely(replaceX, replaceY).TileType == 397)
                            {
                                WorldGen.KillWall(replaceX, replaceY, false);
                                WorldGen.PlaceWall(replaceX, replaceY, 216, false);
                            }
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 112 || Framing.GetTileSafely(replaceX, replaceY).TileType == 398)
                            {
                                WorldGen.KillWall(replaceX, replaceY, false);
                                WorldGen.PlaceWall(replaceX, replaceY, 217, false);
                            }
                            if (Framing.GetTileSafely(replaceX, replaceY).TileType == 234 || Framing.GetTileSafely(replaceX, replaceY).TileType == 399)
                            {
                                WorldGen.KillWall(replaceX, replaceY, false);
                                WorldGen.PlaceWall(replaceX, replaceY, 218, false);
                            }
                        }
                    }
                }
            }
            for (int y = 1; y < Main.maxTilesY; y++)
            {
                for (int x = 1; x < Main.maxTilesX; x++)
                {
                    if (Framing.GetTileSafely(x, y).TileType == 404 && Framing.GetTileSafely(x + 1, y).HasTile && Framing.GetTileSafely(x + 1, y + 1).HasTile && Framing.GetTileSafely(x, y + 1).HasTile && Framing.GetTileSafely(x - 1, y + 1).HasTile && Framing.GetTileSafely(x - 1, y).HasTile && Framing.GetTileSafely(x - 1, y - 1).HasTile && Framing.GetTileSafely(x, y - 1).HasTile && Framing.GetTileSafely(x + 1, y - 1).HasTile && Main.tileSolid[(int)Framing.GetTileSafely(x + 1, y).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(x + 1, y + 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(x, y + 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(x - 1, y + 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(x - 1, y).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(x - 1, y - 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(x, y - 1).TileType] && Main.tileSolid[(int)Framing.GetTileSafely(x + 1, y - 1).TileType])
                    {
                        Framing.GetTileSafely(x, y).WallType = 223;
                    }
                }
            }
        }
        private void DesertPillars(GenerationProgress progress, GameConfiguration configuration)
        {
            progress.Message = "Desert pillars";
            int tilereplaceX = 400;
            int tilereplaceY = 1;
            new Random();
            while (tilereplaceY < Main.worldSurface)
            {
                while (tilereplaceX < Main.maxTilesX - 400)
                {
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType == 53)
                    {
                        Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType = (ushort)ModContent.TileType<Replace4>();
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType == 147)
                    {
                        Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType = (ushort)ModContent.TileType<Replace5>();
                    }
                    tilereplaceX++;
                }
                tilereplaceY++;
                tilereplaceX = 400;
            }
            int structureX = 400;
            int structureY = 1;
            while (structureY < Main.worldSurface)
            {
                while (structureX < Main.maxTilesX - 400)
                {
                    if (Framing.GetTileSafely(structureX, structureY).HasTile && !Framing.GetTileSafely(structureX, structureY - 1).HasTile && (Framing.GetTileSafely(structureX, structureY).TileType == ModContent.TileType<Replace4>() || Framing.GetTileSafely(structureX, structureY).TileType == 112 || Framing.GetTileSafely(structureX, structureY).TileType == 234) && Main.rand.Next(1, 25) == 1)
                    {
                        tilereplaceX = structureX;
                        tilereplaceY = structureY + 3;
                        int pillarsize = Main.rand.Next(6, 12);
                        int loop = pillarsize * 3;
                        while (loop > 0 && pillarsize > 0)
                        {
                            if (Framing.GetTileSafely(structureX, structureY).TileType == ModContent.TileType<Replace4>())
                            {
                                WorldGen.TileRunner(tilereplaceX, tilereplaceY, pillarsize, 1, ModContent.TileType<Replace1>(), true, 0f, 0f, false, false);
                            }
                            if (Framing.GetTileSafely(structureX, structureY).TileType == 112)
                            {
                                WorldGen.TileRunner(tilereplaceX, tilereplaceY, pillarsize, 1, ModContent.TileType<Replace2>(), true, 0f, 0f, false, false);
                            }
                            if (Framing.GetTileSafely(structureX, structureY).TileType == 234)
                            {
                                WorldGen.TileRunner(tilereplaceX, tilereplaceY, pillarsize, 1, ModContent.TileType<Replace3>(), true, 0f, 0f, false, false);
                            }
                            tilereplaceY--;
                            loop--;
                            if (Main.rand.Next(1, 8) == 1)
                            {
                                pillarsize--;
                            }
                        }
                    }
                    structureX++;
                }
                structureY++;
                structureX = 400;
            }
            tilereplaceX = 1;
            tilereplaceY = 1;
            while (tilereplaceY < Main.maxTilesY)
            {
                while (tilereplaceX < Main.maxTilesX)
                {
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType == ModContent.TileType<Replace1>())
                    {
                        WorldGen.KillTile(tilereplaceX, tilereplaceY, false, false, false);
                        if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == 0)
                        {
                            WorldGen.PlaceWall(tilereplaceX, tilereplaceY, ModContent.WallType<Replace6>(), false);
                        }
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType == ModContent.TileType<Replace2>())
                    {
                        WorldGen.KillTile(tilereplaceX, tilereplaceY, false, false, false);
                        if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == 0)
                        {
                            WorldGen.PlaceWall(tilereplaceX, tilereplaceY, ModContent.WallType<Replace7>(), false);
                        }
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType == ModContent.TileType<Replace3>())
                    {
                        WorldGen.KillTile(tilereplaceX, tilereplaceY, false, false, false);
                        if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == 0)
                        {
                            WorldGen.PlaceWall(tilereplaceX, tilereplaceY, ModContent.WallType<Replace8>(), false);
                        }
                    }
                    tilereplaceX++;
                }
                tilereplaceY++;
                tilereplaceX = 1;
            }
            tilereplaceX = 1;
            tilereplaceY = 1;
            while (tilereplaceY < Main.maxTilesY)
            {
                while (tilereplaceX < Main.maxTilesX)
                {
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == ModContent.WallType<Replace6>())
                    {
                        Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType = 187;
                        if (Framing.GetTileSafely(tilereplaceX, tilereplaceY + 1).WallType == 0)
                        {
                            WorldGen.PlaceWall(tilereplaceX, tilereplaceY + 1, ModContent.WallType<Replace6>(), false);
                        }
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == ModContent.WallType<Replace7>())
                    {
                        Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType = 220;
                        if (Framing.GetTileSafely(tilereplaceX, tilereplaceY + 1).WallType == 0)
                        {
                            WorldGen.PlaceWall(tilereplaceX, tilereplaceY + 1, ModContent.WallType<Replace7>(), false);
                        }
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == ModContent.WallType<Replace8>())
                    {
                        Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType = 221;
                        if (Framing.GetTileSafely(tilereplaceX, tilereplaceY + 1).WallType == 0)
                        {
                            WorldGen.PlaceWall(tilereplaceX, tilereplaceY + 1, ModContent.WallType<Replace8>(), false);
                        }
                    }
                    tilereplaceX++;
                }
                tilereplaceY++;
                tilereplaceX = 1;
            }
            tilereplaceX = 1;
            tilereplaceY = 1;
            while (tilereplaceY < Main.maxTilesY)
            {
                while (tilereplaceX < Main.maxTilesX)
                {
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == ModContent.WallType<Replace6>())
                    {
                        WorldGen.KillWall(tilereplaceX, tilereplaceY, false);
                        WorldGen.PlaceWall(tilereplaceX, tilereplaceY, 187, false);
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == ModContent.WallType<Replace7>())
                    {
                        WorldGen.KillWall(tilereplaceX, tilereplaceY, false);
                        WorldGen.PlaceWall(tilereplaceX, tilereplaceY, 220, false);
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).WallType == ModContent.WallType<Replace8>())
                    {
                        WorldGen.KillWall(tilereplaceX, tilereplaceY, false);
                        WorldGen.PlaceWall(tilereplaceX, tilereplaceY, 221, false);
                    }
                    tilereplaceX++;
                }
                tilereplaceY++;
                tilereplaceX = 1;
            }
            tilereplaceX = 1;
            tilereplaceY = 1;
            while (tilereplaceY < Main.maxTilesY)
            {
                while (tilereplaceX < Main.maxTilesX)
                {
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType == (ushort)ModContent.TileType<Replace4>())
                    {
                        Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType = 53;
                    }
                    if (Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType == (ushort)ModContent.TileType<Replace5>())
                    {
                        Framing.GetTileSafely(tilereplaceX, tilereplaceY).TileType = 147;
                    }
                    tilereplaceX++;
                }
                tilereplaceY++;
                tilereplaceX = 1;
            }
        }
        private void OreMeteorites(GenerationProgress progress, GameConfiguration configuration)
        {
            progress.Message = "Meteorites";
            new Random();
            int structureY = 1;
            while (structureY <= Main.worldSurface)
            {
                for (int structureX = 500; structureX < Main.maxTilesX - 500; structureX++)
                {
                    if (Framing.GetTileSafely(structureX, structureY).TileType == 53)
                    {
                        Framing.GetTileSafely(structureX, structureY).TileType = (ushort)ModContent.TileType<Replace1>();
                    }
                    if (Framing.GetTileSafely(structureX, structureY).TileType == 147)
                    {
                        Framing.GetTileSafely(structureX, structureY).TileType = (ushort)ModContent.TileType<Replace2>();
                    }
                }
                structureY++;
            }
            for (int i = 0; i < Main.maxTilesX / 1050; i++)
            {
                int structureX = WorldGen.genRand.Next(600, Main.maxTilesX - 600);
                structureY = 1;
                while (!Framing.GetTileSafely(structureX, structureY).HasTile || !Main.tileSolid[Framing.GetTileSafely(structureX, structureY).TileType] || Framing.GetTileSafely(structureX, structureY).TileType == 192 || Framing.GetTileSafely(structureX, structureY).TileType == 189 || Framing.GetTileSafely(structureX, structureY).TileType == 196)
                {
                    structureY++;
                }
                int size = WorldGen.genRand.Next(6, 10);
                int ore = WorldGen.genRand.Next(4);
                WorldGen.TileRunner(structureX, structureY, size + 6, 1, 37, false, 1f, 0f, false, true);
                if (ore == 0)
                {
                    WorldGen.TileRunner(structureX, structureY, size, 1, 7, true, 1f, 0f, false, true);
                }
                else if (ore == 1)
                {
                    WorldGen.TileRunner(structureX, structureY, size, 1, 166, true, 1f, 0f, false, true);
                }
                else if (ore == 2)
                {
                    WorldGen.TileRunner(structureX, structureY, size, 1, 6, true, 1f, 0f, false, true);
                }
                else if (ore == 3)
                {
                    WorldGen.TileRunner(structureX, structureY, size, 1, 167, true, 1f, 0f, false, true);
                }
            }
            structureY = 1;
            while (structureY <= Main.worldSurface)
            {
                for (int structureX = 400; structureX < Main.maxTilesX - 400; structureX++)
                {
                    if (Framing.GetTileSafely(structureX, structureY).TileType == (ushort)ModContent.TileType<Replace1>())
                    {
                        Framing.GetTileSafely(structureX, structureY).TileType = 53;
                    }
                    if (Framing.GetTileSafely(structureX, structureY).TileType == (ushort)ModContent.TileType<Replace2>())
                    {
                        Framing.GetTileSafely(structureX, structureY).TileType = 147;
                    }
                }
                structureY++;
            }
        }
        private void SmoothDesert(GenerationProgress progress, GameConfiguration gameConfig)
        {
            progress.Message = "Smooth Desert";
            for (int y = 1; y < Main.maxTilesY; y++)
            {
                for (int x = 1; x < Main.maxTilesX; x++)
                {
                    if (Framing.GetTileSafely(x, y).HasTile && Framing.GetTileSafely(x, y).TileType == 53)
                    {
                        int replace2X = x - 1;
                        int replace2Y = y + 1;
                        while (replace2X < x + 2)
                        {
                            if (!Framing.GetTileSafely(replace2X, replace2Y).HasTile || !Main.tileSolid[Framing.GetTileSafely(replace2X, replace2Y).TileType])
                            {
                                WorldGen.PlaceTile(replace2X, replace2Y, 53, false, false, -1, 0);
                            }
                            replace2X++;
                        }
                        if (Framing.GetTileSafely(x + 1, y).HasTile && Framing.GetTileSafely(x + 1, y + 1).HasTile && Framing.GetTileSafely(x, y + 1).HasTile && Framing.GetTileSafely(x - 1, y + 1).HasTile && Framing.GetTileSafely(x - 1, y).HasTile && Framing.GetTileSafely(x - 1, y - 1).HasTile && Framing.GetTileSafely(x, y - 1).HasTile && Framing.GetTileSafely(x + 1, y - 1).HasTile && Main.tileSolid[Framing.GetTileSafely(x + 1, y).TileType] && Main.tileSolid[Framing.GetTileSafely(x + 1, y + 1).TileType] && Main.tileSolid[Framing.GetTileSafely(x, y + 1).TileType] && Main.tileSolid[Framing.GetTileSafely(x - 1, y + 1).TileType] && Main.tileSolid[Framing.GetTileSafely(x - 1, y).TileType] && Main.tileSolid[Framing.GetTileSafely(x - 1, y - 1).TileType] && Main.tileSolid[Framing.GetTileSafely(x, y - 1).TileType] && Main.tileSolid[Framing.GetTileSafely(x + 1, y - 1).TileType])
                        {
                            WorldGen.KillWall(x, y, false);
                            WorldGen.PlaceWall(x, y, 216, false);
                        }
                    }
                }
            }
        }
        private void DungeonChains(GenerationProgress progress, GameConfiguration gameConfig)
        {
            progress.Message = "Dungeon chains";
            Random random = new();
            for (int structureY = (int)Main.worldSurface; structureY < Main.maxTilesY - 200; structureY++)
            {
                for (int structureX = 1; structureX <= Main.maxTilesX; structureX++)
                {
                    if (!Framing.GetTileSafely(structureX, structureY).HasTile && Framing.GetTileSafely(structureX, structureY - 1).HasTile && (Framing.GetTileSafely(structureX, structureY - 1).TileType == 41 || Framing.GetTileSafely(structureX, structureY - 1).TileType == 43 || Framing.GetTileSafely(structureX, structureY - 1).TileType == 44) && Main.wallDungeon[Framing.GetTileSafely(structureX, structureY).WallType] && WorldGen.genRand.NextBool(6))
                    {
                        int x = structureX;
                        int y = structureY;
                        int height = 0;
                        while (!Framing.GetTileSafely(x, y).HasTile)
                        {
                            y++;
                            height++;
                            if (Framing.GetTileSafely(x - 1, y).TileType == 214 || Framing.GetTileSafely(x + 1, y).TileType == 214)
                            {
                                height = -9999;
                                break;
                            }
                        }
                        if (height >= 20)
                        {
                            height -= random.Next(2, height - 10);
                            for (y = structureY; y < structureY + height; y++)
                            {
                                WorldGen.PlaceTile(x, y, 214, false, false, -1, 0);
                            }
                        }
                        if (WorldGen.genRand.NextBool(2))
                        {
                            WorldGen.PlaceTile(x, y, 194, false, false, -1, 0);
                        }
                    }
                }
            }
        }
        private void MegaCaves(GenerationProgress progress, GameConfiguration gameConfig)
        {
            progress.Message = "Mega Caves";
            int structureCount = Main.maxTilesX / 200;
            while (structureCount > 0)
            {
                structureCount--;
                int x = WorldGen.genRand.Next(100, Main.maxTilesX - 100);
                int num = WorldGen.genRand.Next((int)Main.rockLayer, Main.maxTilesY - 200);
                int sizemax = WorldGen.genRand.Next(8, 17);
                int replaceX = x;
                int replaceY = num;
                int size = 6;
                int velX = WorldGen.genRand.Next(-6, 7);
                int velY = WorldGen.genRand.Next(-3, 4);
                bool halfway = false;
                while (size >= 6)
                {
                    int replace2X = replaceX - size;
                    int replace2Y = replaceY - size;
                    while (replace2Y < replaceY + size)
                    {
                        while (replace2X < replaceX + size)
                        {
                            if (Vector2.Distance(new Vector2(replaceX, replaceY), new Vector2(replace2X, replace2Y)) < size && replace2X > 0 && replace2X < Main.maxTilesX && replace2Y < Main.maxTilesY)
                            {
                                WorldGen.KillTile(replace2X, replace2Y, false, false, false);
                            }
                            replace2X++;
                        }
                        replace2Y++;
                        replace2X = replaceX - size;
                    }
                    replaceX += velX;
                    replaceY += velY;
                    velX += WorldGen.genRand.Next(-2, 3);
                    if (velX > 6)
                    {
                        velX = 6;
                    }
                    if (velX < -6)
                    {
                        velX = -6;
                    }
                    velY += WorldGen.genRand.Next(-2, 3);
                    if (velY > 3)
                    {
                        velY = 3;
                    }
                    if (velY < -3)
                    {
                        velY = -3;
                    }
                    if (size > sizemax)
                    {
                        halfway = true;
                    }
                    if (WorldGen.genRand.Next(1, 12) == 1)
                    {
                        if (halfway)
                        {
                            size--;
                        }
                        else
                        {
                            size++;
                        }
                    }
                }
            }
        }
        private void Clay(GenerationProgress progress, GameConfiguration gameConfig)
        {
            progress.Message = "Better Clay";
            for (int y = 1; y < Main.maxTilesY; y++)
            {
                for (int x = 1; x < Main.maxTilesX; x++)
                {
                    if (Framing.GetTileSafely(x, y).HasTile && Main.tile[x, y - 1].LiquidType == 0 && Main.tile[x, y - 1].LiquidAmount > 0)
                    {
                        int x2 = x;
                        int y2 = y;
                        int claydepth = 1;
                        if (Framing.GetTileSafely(x, y).Slope != 0 || Framing.GetTileSafely(x, y).IsHalfBlock)
                        {
                            claydepth++;
                        }
                        y2--;
                        while (Main.tile[x2, y2].LiquidType == 0 && Main.tile[x2, y2].LiquidAmount > 0 && claydepth < 99)
                        {
                            claydepth++;
                            y2--;
                        }
                        for (y2 = y; y2 < y + claydepth; y2++)
                        {
                            if (Framing.GetTileSafely(x2, y2).HasTile && (Framing.GetTileSafely(x2, y2).TileType == 0 || Framing.GetTileSafely(x2, y2).TileType == 2 || Framing.GetTileSafely(x2, y2).TileType == 23 || Framing.GetTileSafely(x2, y2).TileType == 199))
                            {
                                Framing.GetTileSafely(x2, y2).TileType = 40;
                            }
                        }
                    }
                }
            }
        }
        private static void Campfires(GenerationProgress progress, GameConfiguration gameConfig)
        {
            progress.Message = "Campfires";
            int campfires = Main.maxTilesX / 525;
            while (campfires > 0)
            {
                int attempts = 0;
                bool success = false;
                while (!success)
                {
                    attempts++;
                    if (attempts > 1000)
                    {
                        campfires--;
                        break;
                    }
                    int x = WorldGen.genRand.Next(400, Main.maxTilesX - 400);
                    int y = WorldGen.genRand.Next((int)Main.worldSurface / 2, (int)Main.worldSurface);
                    bool valid = true;
                    for (int i = 0; i < 3; i++)
                    {
                        if (Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 19 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 37 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 53 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 112 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 234 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 191 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 192 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 41 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 43 || Framing.GetTileSafely(x - 1 + i, y + 1).TileType == 44)
                        {
                            valid = false;
                        }
                    }
                    if (valid)
                    {
                        WorldGen.PlaceObject(x, y, 215, false, 0, 0, -1, -1);
                        success = Main.tile[x, y].TileType == 215;
                    }
                }
                if (success)
                {
                    campfires--;
                }
            }
        }
    }
}
